/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManagerFactory;
import test.controllers.ActionJpaController;
import test.controllers.EntrepriseJpaController;
import test.controllers.HistoriqueActionJpaController;
import test.controllers.exceptions.PreexistingEntityException;
import test.entities.*;
/**
 *
 * @author Issam
 */
public class controler {
    private EntityManagerFactory emf;
    private Calendar calendrier;
    public controler(EntityManagerFactory emf, Calendar cal)
    {
        this.calendrier = cal;
        this.emf = emf;
    }
 
    private void OrdreDeCroissant(Vector<Float> variation, Vector<String> entreprises)
    {
        float aux_variation;
        String aux_entreprise;
        int j = variation.size() - 1;
        while((j>0)&&(variation.get(j) < variation.get(j-1)))
        {
            aux_variation = variation.get(j);
            aux_entreprise = entreprises.get(j);
            variation.set(j,variation.get(j-1));
            entreprises.set(j,entreprises.get(j-1));
            variation.set(j-1, aux_variation);
            entreprises.set(j-1, aux_entreprise);
            j--;
        }
    }
    
    private void OrdreCroissant(Vector<Float> variation, Vector<String> entreprises)
    {
        float aux_variation;
        String aux_entreprise;
        int j = variation.size() - 1;
        while((j>0)&&(variation.get(j) > variation.get(j-1)))
        {
            aux_variation = variation.get(j);
            aux_entreprise = entreprises.get(j);
            variation.set(j,variation.get(j-1));
            entreprises.set(j,entreprises.get(j-1));
            variation.set(j-1, aux_variation);
            entreprises.set(j-1, aux_entreprise);
            j--;
        }
    }
    
    public String[][] Top5Action(String type)
    {
        return TopAction(type,5);
    }
            
    public String[][] TopAction(String type,int number)
    {
        String[][] result = new String[number][2];
        if(!(type.toLowerCase().equals("hausse") ||type.toLowerCase().equals("baisse")))
        {
            System.out.println("Wrong Type");
            return result;
        }
        int i,j;
        EntrepriseJpaController entrp = new EntrepriseJpaController(this.emf);
        
        Vector<String> entreprises = new Vector<String>();
        Vector<Float> variation = new Vector<Float>();
        float o_val, c_val,var;
                
        List<Entreprise> l_entrp = entrp.findEntrepriseEntities();
        
        Action tempAction;
        HistoriqueAction tempHistAction,HistAction;

        
        for (i=0;i<l_entrp.size();i++)
        {
            if(l_entrp.get(i).getActionCollection().size()>0)
            {
                tempAction = (Action) l_entrp.get(i).getActionCollection().toArray()[0];
                j=1;
                while ((tempAction.getHistoriqueActionCollection().isEmpty()) && (j<l_entrp.get(i).getActionCollection().size()))
                {
                    tempAction = (Action) l_entrp.get(i).getActionCollection().toArray()[j];
                    j++;                    
                }
                c_val =tempAction.getValeurCourante().floatValue();
                if(tempAction.getHistoriqueActionCollection().size()>0) 
                {
                    HistAction = (HistoriqueAction) tempAction.getHistoriqueActionCollection().toArray()[0];
                    for (j=0;j<tempAction.getHistoriqueActionCollection().size();j++)
                    {
                        tempHistAction = (HistoriqueAction) tempAction.getHistoriqueActionCollection().toArray()[j];
                        if(HistAction.getDate().compareTo(tempHistAction.getDate()) < 0 )
                            HistAction = tempHistAction;
                    }
                    o_val = HistAction.getValeur().floatValue();
                    var = c_val - o_val;
                    variation.add(var);
                    entreprises.add(tempAction.getIdEntreprise().getNom());
                    if(type.toLowerCase().equals("hausse"))
                        OrdreCroissant(variation,entreprises);
                    else
                        OrdreDeCroissant(variation, entreprises);
                    
                }
                
            }
        }
        j = (number<variation.size())?number:variation.size();
        for (i=0;i<j;i++)
        {
            if((variation.get(i) > 0 && type.toLowerCase().equals("hausse")) || (variation.get(i) < 0 && type.toLowerCase().equals("baisse")))
            {
                result[i][0] = entreprises.get(i);
                result[i][1] = String.valueOf(variation.get(i));
                System.out.println(result[i][0]+"\t"+result[i][1]);
            }
        }
        return result;
        
   }
    
   
   public int edit_action(double val,Entreprise e) 
   {
       emf =this.emf;
       BigDecimal value = BigDecimal.valueOf(val);
       BigDecimal o_val;
       ActionJpaController c_act = new ActionJpaController(emf);
       HistoriqueActionJpaController c_hist = new HistoriqueActionJpaController(emf);
       Action aux;
       HistoriqueAction hist = new HistoriqueAction() ;
       int n = e.getActionCollection().size();
       Date d = new Date(calendrier.getTimeInMillis());
       
       if (n > 0)
       {
           aux = (Action) e.getActionCollection().toArray()[0];
           o_val = aux.getValeurCourante();
           if ( o_val.compareTo(value) == 0 )
           {
               return 3;  // Valeur Existe deja
           }
           for (int i=0;i<n;i++)
           {
                aux = (Action) e.getActionCollection().toArray()[i];
                hist = new HistoriqueAction();
                hist.setValeur(o_val);
                hist.setDate(d);
                hist.setNumAction(aux);
                try {
                    c_hist.create(hist);
                    c_hist.edit(hist);
                    aux.setValeurCourante(value);
                    c_act.edit(aux);
                } catch (Exception ex) {
                    return 2; // probleme de persistance
                }
                
            }
           
           return 0;
       }
       else
       {
            if (add_action(val,d ,e)==0)
                return 0;
            return 1; // probleme d'enregistrement
       }
           
   } 
    
   public int add_action(double val,Date d,Entreprise e) 
   {
       emf = this.emf;
       BigDecimal value = BigDecimal.valueOf(val);
       ActionJpaController c_act = new ActionJpaController(emf);
       Action act = new Action();
       act.setDateEmission(d);
       act.setIdEntreprise(e);
       if (e.getActionCollection().size() > 0)
       {
           return 1;
       }
       act.setValeurCourante(value);
        try {
            c_act.create(act);
            return 0;
        } catch (Exception ex) {
            return 2;
        }
   }
   
   public boolean add_action(Date d,Entreprise e) 
   {
       emf = this.emf;
       BigDecimal value = BigDecimal.valueOf(0);
       ActionJpaController c_act = new ActionJpaController(emf);
       Action act = new Action();
       Action aux;
       act.setDateEmission(d);
       act.setIdEntreprise(e);
       if (e.getActionCollection().size() > 0)
       {
           aux = (Action) e.getActionCollection().toArray()[0];
           value = aux.getValeurCourante();
       }
       act.setValeurCourante(value);
        try {
            c_act.create(act);
            return true;
        } catch (Exception ex) {
            return false;
        }
   }
   
   public String[][]  ActionEvolution(Entreprise e)
   {
       String[][] result = new String[0][0];
       Vector<String> date_hist = new Vector<String>(),date_hist1 = new Vector<String>();
       Vector<Float> val= new Vector<Float>(),val1 = new Vector<Float>();
       Vector<Date> vect_date = new Vector<Date>();
       List<Action> l_action = (List<Action>) e.getActionCollection();
       if (l_action.size()>0)
       {
            Action aux_Action=l_action.get(0); 
            // l'action qui a le plus d'historique
            for(int i=1;i<l_action.size();i++)
            {
                if(l_action.get(i).getHistoriqueActionCollection().size() > aux_Action.getHistoriqueActionCollection().size())
                    aux_Action = l_action.get(i);
            }
            int n = aux_Action.getHistoriqueActionCollection().size();
            String format = "dd-MM-yyyy";
            List<HistoriqueAction> histArray = (List<HistoriqueAction>) aux_Action.getHistoriqueActionCollection();
            SimpleDateFormat Date_format = new SimpleDateFormat( format );
            
            vect_date.add(aux_Action.getDateEmission());
            for (int j=0;j<n;j++)
            {
                val.add(histArray.get(j).getValeur().floatValue());
                vect_date.add(histArray.get(j).getDate());
            }
            val.add(aux_Action.getValeurCourante().floatValue());
            // Tri 
            int k;
            Date aux;float f;
            for(int j=0;j<n+1;j++)
            {
                k=j-1;
                while(k>0 && vect_date.get(j).after(vect_date.get(k)))
                {
                    f = val.get(j);
                    aux = vect_date.get(j);
                    val.set(j, val.get(k));
                    vect_date.set(j, vect_date.get(k));
                    val.set(k, f);
                    vect_date.set(k, aux);                    
                    k--;
                }
                calendrier.setTime(vect_date.get(j));
                date_hist.add(Date_format.format(vect_date.get(j)));
            }

            // Calcul de moyenne par jour
            int same_date=1,last_index=0;
            float total=val.get(0);
            for(int j =0 ;j<n+1;j++)
            {
                if(date_hist.get(j).equals(date_hist.get(last_index)))
                        {
                            total += val.get(j);
                            same_date++;
                            if(j==n)
                            {
                                val1.add(total/same_date);
                                date_hist1.add(date_hist.get(j));
                            }
                        }
                else
                {
                    total/=same_date;
                    val1.add(total);
                    date_hist1.add(date_hist.get(last_index));
                    same_date = 1;
                    total =val.get(j);
                    last_index =j;
                }
            }
           
            n = val1.size();
            result = new String[n][2]; 
            String aux_date,aux_val;
            // colonne 1 : Date ** colonne 2 : Value
            for(int j =0 ;j<n;j++)
            {
                result[j][0] = val1.get(j).toString(); 
                result[j][1]   = date_hist1.get(j).toString();
            }
            for(int j=0;j<n;j++)
            {
                System.out.println(result[j][0]+"\t"+result[j][1]);
            }
            
            
            
       }
       return result;
   }
}
    